package mfuny.ggongal.admin.play;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import mfuny.ggongal.admin.Server;
import mfuny.ggongal.admin.ad.AdDao;
import mfuny.ggongal.admin.ad.AdDetail;
import mfuny.ggongal.admin.ad.MissionDetail;

import com.ibatis.sqlmap.client.SqlMapClient;

public class PlayService {
	SqlMapClient sqlMapper;
	
	public PlayService() throws Exception {
		sqlMapper = Server.getSqlMapper();
	}
	
	//당첨자 리스트 가져오기.
	@SuppressWarnings({ "unchecked", "deprecation" })
	public List<Object> getWinnerForAd(int ad_no, Date time) throws Exception {
		
		// vc23 업데이트 이전과 이후 당첨자 리스트 구분.
		if( AdDetail.vc23Date.getTime() < time.getTime() ) {
			return getWinnerForAd26(ad_no, time);
		}
		
		
		HashMap<String, Object> ad = (HashMap<String, Object>)sqlMapper.queryForObject("ad_selectAllOne2", ad_no);
		String fullMission = (String)ad.get("mission");
		
		//미션점수.
		int m_score = MissionDetail.getScore_mission(fullMission);
		
		// 시간대 설정.
		time.setMinutes(0);
		time.setSeconds(0);
		Date starttime = (Date) time.clone();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		//경품 종류별.
		String[] gifts = fullMission.split("/")[2].split("\\|");
		
		//리스트 가져오기.
		List<Object>[] lists = new ArrayList[gifts.length];
		for(int i = 0; i < lists.length; i++) {
			int limitstart = MissionDetail.getLimitStart_mission(gifts[i]);
			int limitend = MissionDetail.getLimitEnd_mission(gifts[i]);
			
			HashMap<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("score", m_score);
			paramMap.put("ad_no", ad_no);
			paramMap.put("starttime", formatter.format(starttime));
			paramMap.put("limitstart", limitstart);
			paramMap.put("limitend", limitend);
			
			if (((String)ad.get("service")).equals("special")) {
				lists[i] = sqlMapper.queryForList("play_selectWinner20", paramMap);
			}
			
			for(int j = 0; j < lists[i].size(); j++) {
				HashMap<String, Object> map = (HashMap<String, Object>) lists[i].get(j);
				HashMap<String, Object> giftDetail = MissionDetail.getGiftDetail_mission(gifts[i]);
				paramMap.put("id", map.get("id"));
				HashMap<String, Object> myGiftInfo = (HashMap<String, Object>)sqlMapper.queryForObject("myGift_selectForShip", paramMap);
				map.put("mygift_no", myGiftInfo == null ? null : myGiftInfo.get("mygift_no"));			//배송관리용.
				map.put("isreceive", myGiftInfo == null ? null : myGiftInfo.get("isreceive"));					//배송관리용.
				map.put("recipient", myGiftInfo == null ? null : myGiftInfo.get("recipient"));				//배송관리용.
				map.put("invoicenum", myGiftInfo == null ? null : myGiftInfo.get("invoicenum"));		//배송관리용.
				map.put("giftId", giftDetail.get("giftId"));
				map.put("giftType", giftDetail.get("giftType"));
				map.put("giftName", giftDetail.get("giftName"));
				map.put("gameendtime", "" + map.get("gameendtime"));
//				map.put("rank", MissionDetail.getLimitStart_mission(gifts[i]) + 1 + j );
				lists[i].set(j, map);
			}
		}
		
		//리스트 하나로 합치기.
		List<Object> winnerList = new ArrayList<Object>();
		for(int i = 0; i < lists.length; i++) {
			for(int j = 0; j < lists[i].size(); j++) {
				HashMap<String, Object> map = (HashMap<String, Object>) lists[i].get(j);
				map.put("rank", (int)Float.parseFloat(map.get("rank")+""));
				winnerList.add(map);
			}
		}
		
		return winnerList;
	}
	
	//당첨자 리스트 가져오기. (vc-26) 속도 개선함.
	@SuppressWarnings({ "unchecked", "deprecation" })
	public List<Object> getWinnerForAd26(int ad_no, Date time) throws Exception {
		HashMap<String, Object> ad = (HashMap<String, Object>)sqlMapper.queryForObject("ad_selectAllOne2", ad_no);
		String fullMission = (String)ad.get("mission");
		
		// 시간대 설정.
		time.setMinutes(0);
		time.setSeconds(0);
		Date starttime = (Date) time.clone();
		
		//당첨 등수 리스트 구하기(몇등이 당첨인지).
		List<Integer> winNumList = MissionDetail.getWinRankNum_mission(fullMission);
		
		//select 용 파라미터 구하기.
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("ad_no", ad_no);
		paramMap.put("starttime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(starttime));
		paramMap.put("winNumList", winNumList);
		paramMap.put("hour", AdDetail.vc27Hour);					//3시간.
		if( time.getTime() >= AdDetail.vc27Date.getTime() ) {
			paramMap.put("minute", AdDetail.vc27Minute);			//vc-27 0분 정시.
		} else {
			paramMap.put("minute", AdDetail.vc23Minute);			//vc-23~26 +2분.
		}
		
		// winner 테이블에 해당 날짜의 리스트 가져오기.
		List<Object> winnerList = sqlMapper.queryForList("winner_select", starttime);
		
		// 리스트 갯수가 1 이상이면 패스.
		
		// 리스트 갯수가 0 이하면 기존방식 리스트 구하기.
		if( winnerList == null || winnerList.size() <= 0 ) {
			winnerList = sqlMapper.queryForList("play_selectWinner27", paramMap);
			
			// 기존방식 리스트 갯수가 1 이상이면.
			if( winnerList != null && winnerList.size() > 0 ) {
				try {
					sqlMapper.startTransaction();
					// winner 테이블의 해당 날짜 데이터 삭제 (안전을 위한 삭제).
					sqlMapper.delete("winner_delete", starttime);
					// winner 테이블에 기존 방식으로 구한 데이터를 삽입 후 패스.
					sqlMapper.insert("winner_insert", paramMap);
					
					sqlMapper.commitTransaction();
				} catch( Exception e ) {} 
				finally {
					sqlMapper.endTransaction();
				}
				
				
			} else {
			// 기존 방식 리스트 갯수가 0 이하면 종료.
				return winnerList;
			}
		}
		
		// 추가 정보 붙이기.
		for(int i = 0; i < winnerList.size(); i++) {
			HashMap<String, Object> map = (HashMap<String, Object>) winnerList.get(i);
			paramMap.put("id", map.get("id"));
			HashMap<String, Object> myGiftInfo = (HashMap<String, Object>)sqlMapper.queryForObject("myGift_selectForShip", paramMap);
			
			//배송관리용.
			map.put("mygift_no", myGiftInfo == null ? null : myGiftInfo.get("mygift_no"));
			map.put("isreceive", myGiftInfo == null ? null : myGiftInfo.get("isreceive"));
			map.put("recipient", myGiftInfo == null ? null : myGiftInfo.get("recipient"));
			map.put("invoicenum", myGiftInfo == null ? null : myGiftInfo.get("invoicenum"));
			
			//당첨된 경품정보.
			HashMap<String, Object> giftDetail = MissionDetail.getGiftDetailByRank2_mission(fullMission, (int)(double)Double.parseDouble(String.valueOf(map.get("rank"))));
			map.put("giftId", giftDetail.get("giftId"));
			map.put("giftType", giftDetail.get("giftType"));
			map.put("giftName", giftDetail.get("giftName"));
			map.put("gameendtime", "" + map.get("gameendtime"));
			winnerList.set(i, map);
		}
		
		return winnerList;
	}
	
	//특정타임게임에서 당첨된 ID의 유져 플레이 제한(당첨여부).
	@SuppressWarnings("deprecation")
	public boolean isWin(String id, int ad_no) throws Exception {
		Date starttime = new Date();
		starttime.setHours(0);
		starttime.setMinutes(0);
		starttime.setSeconds(0);
		
		Date endtime = (Date)starttime.clone();
		endtime.setDate(endtime.getDate() + 1);
		
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", ad_no);
		if(!ad.getService().equals("time")) {
			return false;
		}
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("id", id);
		paramMap.put("ad_no", ad_no);
		paramMap.put("starttime", starttime);
		paramMap.put("endtime", endtime);
		paramMap.put("score", MissionDetail.getScore_mission(ad.getMission()));
		
		Object sqlObj = sqlMapper.queryForObject("play_getRankByIdForTime", paramMap);
		boolean isWin = false;
		
		if(sqlObj != null) {
			isWin = true;
		}
		
		return isWin;
	}
	
	//특정타임게임의 경품이 소진되었는지 여부.
	@SuppressWarnings("deprecation")
	public boolean isDrained(int ad_no) throws Exception {
		boolean isDrained = false;
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", ad_no);
		
		Date starttime = new Date();
		starttime.setHours(0);
		starttime.setMinutes(0);
		starttime.setSeconds(0);
		Date endtime = (Date)starttime.clone();
		endtime.setDate(endtime.getDate() + 1);
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("ad_no", ad_no);
		paramMap.put("starttime", starttime);
		paramMap.put("endtime", endtime);
		paramMap.put("score", MissionDetail.getScore_mission(ad.getMission()));
		
		int lastRank = MissionDetail.getLastWinRank_mission(ad.getMission());
		int winCount = (Integer)sqlMapper.queryForObject("play_selectWinCountForTime", paramMap);
		
		if(winCount >= lastRank) {
			isDrained = true;
		}
		
		return isDrained;
	}
}
